#include "StdAfx.h"

#include "NumberUtils.h"

#include <cstdio>

#define I64_FMT "I64"

void AppendNumber(std::string& str, int value)
{
	char buffer[64];
	std::sprintf(buffer, "%d", value);
	str.append(buffer);
}


void AppendNumber(std::string& str, int value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%*d", width, value);
	str.append(buffer);
}


void AppendNumber0(std::string& str, int value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%0*d", width, value);
	str.append(buffer);
}


void AppendNumberHex(std::string& str, int value)
{
	char buffer[64];
	std::sprintf(buffer, "%X", value);
	str.append(buffer);
}


void AppendNumberHex(std::string& str, int value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%0*X", width, value);
	str.append(buffer);
}


void AppendNumber(std::string& str, unsigned value)
{
	char buffer[64];
	std::sprintf(buffer, "%u", value);
	str.append(buffer);
}


void AppendNumber(std::string& str, unsigned value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%*u", width, value);
	str.append(buffer);
}


void AppendNumber0(std::string& str, unsigned int value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%0*u", width, value);
	str.append(buffer);
}


void AppendNumberHex(std::string& str, unsigned value)
{
	char buffer[64];
	std::sprintf(buffer, "%X", value);
	str.append(buffer);
}


void AppendNumberHex(std::string& str, unsigned value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%0*X", width, value);
	str.append(buffer);
}


void AppendNumber(std::string& str, long value)
{
	char buffer[64];
	std::sprintf(buffer, "%ld", value);
	str.append(buffer);
}


void AppendNumber(std::string& str, long value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%*ld", width, value);
	str.append(buffer);
}


void AppendNumber0(std::string& str, long value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%0*ld", width, value);
	str.append(buffer);
}


void AppendNumberHex(std::string& str, long value)
{
	char buffer[64];
	std::sprintf(buffer, "%lX", value);
	str.append(buffer);
}


void AppendNumberHex(std::string& str, long value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%0*lX", width, value);
	str.append(buffer);
}


void AppendNumber(std::string& str, unsigned long value)
{
	char buffer[64];
	std::sprintf(buffer, "%lu", value);
	str.append(buffer);
}


void AppendNumber(std::string& str, unsigned long value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%*lu", width, value);
	str.append(buffer);
}


void AppendNumber0(std::string& str, unsigned long value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%0*lu", width, value);
	str.append(buffer);
}


void AppendNumberHex(std::string& str, unsigned long value)
{
	char buffer[64];
	std::sprintf(buffer, "%lX", value);
	str.append(buffer);
}


void AppendNumberHex(std::string& str, unsigned long value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%0*lX", width, value);
	str.append(buffer);
}

void AppendNumber(std::string& str, int64_t value)
{
	char buffer[64];
	std::sprintf(buffer, "%"I64_FMT"d", value);
	str.append(buffer);
}


void AppendNumber(std::string& str, int64_t value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%*"I64_FMT"d", width, value);
	str.append(buffer);
}


void AppendNumber0(std::string& str, int64_t value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%0*"I64_FMT"d", width, value);
	str.append(buffer);
}


void AppendNumberHex(std::string& str, int64_t value)
{
	char buffer[64];
	std::sprintf(buffer, "%"I64_FMT"X", value);
	str.append(buffer);
}


void AppendNumberHex(std::string& str, int64_t value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%0*"I64_FMT"X", width, value);
	str.append(buffer);
}


void AppendNumber(std::string& str, uint64_t value)
{
	char buffer[64];
	std::sprintf(buffer, "%"I64_FMT"u", value);
	str.append(buffer);
}


void AppendNumber(std::string& str, uint64_t value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%*"I64_FMT"u", width, value);
	str.append(buffer);
}


void AppendNumber0(std::string& str, uint64_t value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%0*"I64_FMT"u", width, value);
	str.append(buffer);
}


void AppendNumberHex(std::string& str, uint64_t value)
{
	char buffer[64];
	std::sprintf(buffer, "%"I64_FMT"X", value);
	str.append(buffer);
}


void AppendNumberHex(std::string& str, uint64_t value, int width)
{
	ASSERT (width > 0 && width < 64);

	char buffer[64];
	std::sprintf(buffer, "%0*"I64_FMT"X", width, value);
	str.append(buffer);
}


void AppendNumber(std::string& str, float value)
{
	char buffer[64];
	std::sprintf(buffer, "%.*g", 8, (double) value);
	str.append(buffer);
}


void AppendNumber(std::string& str, double value)
{
	char buffer[64];
	std::sprintf(buffer, "%.*g", 16, value);
	str.append(buffer);
}


void AppendNumber(std::string& str, double value, int precision)
{
	ASSERT (precision >= 0 && precision < 32);

	char buffer[64];
	std::sprintf(buffer, "%.*f", precision, value);
	str.append(buffer);
}


void AppendNumber(std::string& str, double value, int width, int precision)
{
	ASSERT (width > 0 && width < 64 && precision >= 0 && precision < width);

	char buffer[64];
	std::sprintf(buffer, "%*.*f", width, precision, value);
	str.append(buffer);
}


void AppendNumber(std::string& str, const void* ptr)
{
	char buffer[24];
	std::sprintf(buffer, "%p", ptr);
	str.append(buffer);
}



std::string FormatNumber(int value)
{
	std::string result;
	AppendNumber(result, value);
	return result;
}


std::string FormatNumber(int value, int width)
{
	std::string result;
	AppendNumber(result, value, width);
	return result;
}


std::string FormatNumber0(int value, int width)
{
	std::string result;
	AppendNumber0(result, value, width);
	return result;
}


std::string FormatNumberHex(int value)
{
	std::string result;
	AppendNumberHex(result, value);
	return result;
}


std::string FormatNumberHex(int value, int width)
{
	std::string result;
	AppendNumberHex(result, value, width);
	return result;
}


std::string FormatNumber(unsigned value)
{
	std::string result;
	AppendNumber(result, value);
	return result;
}


std::string FormatNumber(unsigned value, int width)
{
	std::string result;
	AppendNumber(result, value, width);
	return result;
}


std::string FormatNumber0(unsigned int value, int width)
{
	std::string result;
	AppendNumber0(result, value, width);
	return result;
}


std::string FormatNumberHex(unsigned value)
{
	std::string result;
	AppendNumberHex(result, value);
	return result;
}


std::string FormatNumberHex(unsigned value, int width)
{
	std::string result;
	AppendNumberHex(result, value, width);
	return result;
}


std::string FormatNumber(long value)
{
	std::string result;
	AppendNumber(result, value);
	return result;
}


std::string FormatNumber(long value, int width)
{
	std::string result;
	AppendNumber(result, value, width);
	return result;
}


std::string FormatNumber0(long value, int width)
{
	std::string result;
	AppendNumber0(result, value, width);
	return result;
}


std::string FormatNumberHex(long value)
{
	std::string result;
	AppendNumberHex(result, value);
	return result;
}


std::string FormatNumberHex(long value, int width)
{
	std::string result;
	AppendNumberHex(result, value, width);
	return result;
}


std::string FormatNumber(unsigned long value)
{
	std::string result;
	AppendNumber(result, value);
	return result;
}


std::string FormatNumber(unsigned long value, int width)
{
	std::string result;
	AppendNumber(result, value, width);
	return result;
}


std::string FormatNumber0(unsigned long value, int width)
{
	std::string result;
	AppendNumber0(result, value, width);
	return result;
}


std::string FormatNumberHex(unsigned long value)
{
	std::string result;
	AppendNumberHex(result, value);
	return result;
}


std::string FormatNumberHex(unsigned long value, int width)
{
	std::string result;
	AppendNumberHex(result, value, width);
	return result;
}



std::string FormatNumber(int64_t value)
{
	std::string result;
	AppendNumber(result, value);
	return result;
}


std::string FormatNumber(int64_t value, int width)
{
	std::string result;
	AppendNumber(result, value, width);
	return result;
}


std::string FormatNumber0(int64_t value, int width)
{
	std::string result;
	AppendNumber0(result, value, width);
	return result;
}


std::string FormatNumberHex(int64_t value)
{
	std::string result;
	AppendNumberHex(result, value);
	return result;
}


std::string FormatNumberHex(int64_t value, int width)
{
	std::string result;
	AppendNumberHex(result, value, width);
	return result;
}


std::string FormatNumber(uint64_t value)
{
	std::string result;
	AppendNumber(result, value);
	return result;
}


std::string FormatNumber(uint64_t value, int width)
{
	std::string result;
	AppendNumber(result, value, width);
	return result;
}


std::string FormatNumber0(uint64_t value, int width)
{
	std::string result;
	AppendNumber0(result, value, width);
	return result;
}


std::string FormatNumberHex(uint64_t value)
{
	std::string result;
	AppendNumberHex(result, value);
	return result;
}


std::string FormatNumberHex(uint64_t value, int width)
{
	std::string result;
	AppendNumberHex(result, value, width);
	return result;
}

std::string FormatNumber(float value)
{
	std::string result;
	AppendNumber(result, value);
	return result;
}


std::string FormatNumber(double value)
{
	std::string result;
	AppendNumber(result, value);
	return result;
}


std::string FormatNumber(double value, int precision)
{
	std::string result;
	AppendNumber(result, value, precision);
	return result;
}


std::string FormatNumber(double value, int width, int precision)
{
	std::string result;
	AppendNumber(result, value, width, precision);
	return result;
}


std::string FormatNumber(const void* ptr)
{
	std::string result;
	AppendNumber(result, ptr);
	return result;
}



int ParseInt(const std::string& s)
{
	int result;
	if (!TryParseInt(s, result))
		ThrowException<ParseException>("Not a valid integer", s);
	return result;
}


bool TryParseInt(const std::string& s, int& value)
{
	char temp;
	return std::sscanf(s.c_str(), "%d%c", &value, &temp) == 1;
}


unsigned ParseUnsignedInt(const std::string& s)
{
	unsigned result;
	if (!TryParseUnsignedInt(s, result))
		ThrowException<ParseException>("Not a valid unsigned integer", s);
	return result;
}


bool TryParseUnsignedInt(const std::string& s, unsigned& value)
{
	char temp;
	return std::sscanf(s.c_str(), "%u%c", &value, &temp) == 1;
}


unsigned ParseHex(const std::string& s)
{
	unsigned result;
	if (!TryParseHex(s, result))
		ThrowException<ParseException>("Not a valid hexadecimal integer", s);
	return result;
}


bool TryParseHex(const std::string& s, unsigned& value)
{
	char temp;
	return std::sscanf(s.c_str(), "%x%c", &value, &temp) == 1;
}


int64_t ParseInt64(const std::string& s)
{
	int64_t result;
	if (!TryParseInt64(s, result))
		ThrowException<ParseException>("Not a valid integer", s);
	return result;
}


bool TryParseInt64(const std::string& s, int64_t& value)
{
	char temp;
	return std::sscanf(s.c_str(), "%"I64_FMT"d%c", &value, &temp) == 1;
}


uint64_t ParseUnsignedInt64(const std::string& s)
{
	uint64_t result;
	if (!TryParseUnsignedInt64(s, result))
		ThrowException<ParseException>("Not a valid unsigned integer", s);
	return result;
}


bool TryParseUnsignedInt64(const std::string& s, uint64_t& value)
{
	char temp;
	return std::sscanf(s.c_str(), "%"I64_FMT"u%c", &value, &temp) == 1;
}


uint64_t ParseHex64(const std::string& s)
{
	uint64_t result;
	if (!TryParseHex64(s, result))
		ThrowException<ParseException>("Not a valid hexadecimal integer", s);
	return result;
}


bool TryParseHex64(const std::string& s, uint64_t& value)
{
	char temp;
	return std::sscanf(s.c_str(), "%"I64_FMT"x%c", &value, &temp) == 1;
}

double ParseDouble(const std::string& s)
{
	double result;
	if (!TryParseDouble(s, result))
		ThrowException<ParseException>("Not a valid floating-point number", s);
	return result;
}

bool TryParseDouble(const std::string& s, double& value)
{
	char temp;
	return std::sscanf(s.c_str(), "%lf%c", &value, &temp) == 1;
}
